package online.inote.mapper.configure;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import online.inote.mapper.core.ExtendGenerator;
import online.inote.mapper.core.ExtendMapperProperties;
import tk.mybatis.mapper.autoconfigure.MapperAutoConfiguration;
import tk.mybatis.mapper.autoconfigure.MapperProperties;
import tk.mybatis.spring.mapper.ClassPathMapperScanner;
import tk.mybatis.spring.mapper.MapperFactoryBean;

/**
 * <p>
 * Desc: 动态生成 Mapper Configuration
 * </p>
 *
 * @author Sui
 * @created: 2017年12月10日 上午11:25:05
 * @version 1.0
 */
@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties({ MapperProperties.class, ExtendMapperProperties.class })
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@AutoConfigureBefore(MapperAutoConfiguration.class)
public class ExtendMapperConfiguration {

	private static final Logger logger = LoggerFactory.getLogger(ExtendMapperConfiguration.class);

    public static class AutoConfiguredExtendMapperScannerRegistrar
            implements BeanFactoryAware, ImportBeanDefinitionRegistrar, EnvironmentAware {

        private BeanFactory beanFactory;
        private Environment environment;

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            logger.debug("Generating Mapper with @GenerateMapper...");

            ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
            scanner.setMapperProperties(environment);
            
			ExtendGenerator.getInstance(beanFactory, scanner.getMapperHelper(), environment).start();

            logger.debug("ExtendMapper generation end.");
        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }

        @Override
        public void setEnvironment(Environment environment) {
            this.environment = environment;
        }
    }

    @org.springframework.context.annotation.Configuration
    @Import({AutoConfiguredExtendMapperScannerRegistrar.class})
    @ConditionalOnMissingBean(MapperFactoryBean.class)
    public static class ImportExtendMapper {
    	
    }
}